package com.funny.stock.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.funny.stock.base.exception.BizException;
import com.funny.stock.base.util.ResultUtil;
import com.funny.stock.base.vo.Result;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.servlet.NoHandlerFoundException;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@ControllerAdvice
public class GlobalExceptionHandler {
    private final static Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    @ExceptionHandler({BizException.class, HttpMessageNotReadableException.class, HttpMediaTypeNotSupportedException.class, MaxUploadSizeExceededException.class, HttpRequestMethodNotSupportedException.class, MethodArgumentNotValidException.class, BindException.class,})
    Object serverExceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception e) {
        BizException baseException = null;
        response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
//        response.setStatus(500);
        int msgCode;
        Result result;

        if (e instanceof BizException) {
            baseException = (BizException) e;
            msgCode = baseException.getCode();
            logger.error("异常信息:", e);
            result = ResultUtil.error( msgCode, baseException.getMessage());
        } else if (e instanceof HttpMessageNotReadableException) {
            result = ResultUtil.error( "缺少必须的参数");
        } else if (e instanceof HttpMediaTypeNotSupportedException) {
            result = ResultUtil.error( "请求类型不匹配");
        } else if (e instanceof MaxUploadSizeExceededException) {
            result = ResultUtil.error( "请不要上传超过10MB的文件");
        } else if (e instanceof HttpRequestMethodNotSupportedException) {
            result = ResultUtil.error( "不支持该类型的请求");
        } else if (e instanceof MethodArgumentNotValidException) {
            result = ResultUtil.error( ((MethodArgumentNotValidException) e).getBindingResult().getFieldError().getDefaultMessage());
        } else if (e instanceof BindException) {
            logger.error("异常信息:", e);
            result = ResultUtil.error( ((BindException) e).getBindingResult().getFieldError().getDefaultMessage());
        } else {
            result = ResultUtil.error(ResultUtil.MSG_FAIL);
        }

        try (PrintWriter printWriter = response.getWriter()) {
            printWriter.write(OBJECT_MAPPER.writeValueAsString(result));
        } catch (IOException e1) {
        }
        return null;
    }


    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Object defaultErrorHandler(HttpServletRequest request,HttpServletResponse response,Exception e) {

        if (e instanceof NoHandlerFoundException) {
            String path = request.getServletPath();
            if(AppConstant.LOGIN_URL.equals(path)){
                response.setStatus(HttpStatus.UNAUTHORIZED.value());
                return ResultUtil.error(HttpStatus.UNAUTHORIZED);
            }else{
                response.setStatus(HttpStatus.NOT_FOUND.value());
                return ResultUtil.error(HttpStatus.NOT_FOUND);
            }
        } else {
            logger.error("异常信息:", e);
            response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
            return ResultUtil.error(e.getMessage());
        }
    }

}